package com.javaxiaobang.config;


import com.javaxiaobang.thread.HystrixThreadLocalManager;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixThreadPoolKey;
import com.netflix.hystrix.HystrixThreadPoolProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.client.RestTemplate;

////这一个接口有效
@Slf4j
public class CommandForIndex extends HystrixCommand<Object> {

    private final RestTemplate template;

    private String id;

    public CommandForIndex(String id, RestTemplate restTemplate) {

        // java代码配置， 只针对这个命令
        super(Setter
                // 必填项。指定命令分组名，主要意义是用于统计
                .withGroupKey(HystrixCommandGroupKey.Factory.asKey("java潇邦组"))
                // 依赖名称（如果是服务调用，这里就写具体的接口名， 如果是自定 义的操作，就自己命令），默认是command实现类的类名。 熔断配置就是根据这个名称
                .andCommandKey(HystrixCommandKey.Factory.asKey("ConsumerController"))
                // 线程池命名，默认是HystrixCommandGroupKey的名称。 线程池配置就是根据这个名称
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("java潇邦线程池"))
                // command 熔断相关参数配置
                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                                // 配置隔离方式：默认采用线程池隔离。还有一种信号量(没有队列的线程池)隔离方式,
//                                 .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
                                // 超时时间500毫秒
                                .withExecutionTimeoutInMilliseconds(100)

                        // 信号量隔离的模式下，最大的请求数。和线程池大小的意义一样
                        // .withExecutionIsolationSemaphoreMaxConcurrentRequests(2)
                        // 熔断时间（熔断开启后，各5秒后进入半开启状态，试探是否恢复正常）
                        // .withCircuitBreakerSleepWindowInMilliseconds(5000)
                )
                // 设置线程池参数
                .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
                        // 线程池大小
                        .withCoreSize(1)
                        //允许最大的缓冲区大小
                        .withMaxQueueSize(2)
                ));
        // super(HystrixCommandGroupKey.Factory.asKey("Hystrix-javaxiaobang-command"),100);
        this.id = id;
        this.template = restTemplate;
        HystrixThreadLocalManager.setName();
        Object threadName = HystrixThreadLocalManager.getName();
        log.info(threadName + "");
    }

    @Override
    protected Object run() throws Exception {
        Object threadName = HystrixThreadLocalManager.getName();
        log.info("###command#######" + threadName);
        Object result = template.getForObject("http://clientapp/getDictList", Object.class);
        log.info("###command结束#######" + threadName + ">><>>>服务端返回结果:" + result.toString());
        return result;
    }

    /**
     * 降级的处理：
     * 1.返回一个固定的值
     * 2.去查询缓存
     * 3.调用一个备用接口
     */
    @Override
    protected Object getFallback() {
        Object threadName = HystrixThreadLocalManager.getName();
        String msg = "###服务降级啦####" + threadName;
        log.error(msg);
        return msg;
    }
}
